﻿using System.Security.Claims;
using FlyingHat.Common.Global;
using FlyingHat.Common.Helper;
using FlyingHat.Common.Helper.Image;
using FlyingHat.Model.Enums;
using FlyingHat.Model.Models.Global;
using FlyingHat.Service.IService;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;

namespace FlyingHat.Web.Controllers
{
    public class LoginController : Controller
    {
        private readonly ILogger<LoginController> logger;
        private readonly IUserService userService;
        private readonly CaptchaHelper captchaHelper;
        public LoginController(ILogger<LoginController> logger, IUserService userService, CaptchaHelper captchaHelper)
        {
            this.logger = logger;
            this.userService = userService;
            this.captchaHelper = captchaHelper;
        }

        public async Task<IActionResult> Index()
        {
            // 只要进入登录页就清除登录状态
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return View();
        }
        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <returns></returns>
        public IActionResult GetCaptcha()
        {
            // 获取验证码
            var code = captchaHelper.GetRandomText();
            var by = captchaHelper.GetGifCodeByte(code);
            // 存储验证码
            HttpContext.Session.SetString(GlobalConst.CaptchaSessionName, code);
            return File(by, "image/gif");
        }
        [HttpPost]
        public async Task<IActionResult> Login(string userName, string password, string captcha, bool remember)
        {
            try
            {
                var checkcode = HttpContext.Session.GetString(GlobalConst.CaptchaSessionName);
                if (string.IsNullOrWhiteSpace(checkcode) || !checkcode.Equals(captcha, StringComparison.OrdinalIgnoreCase))
                {
                    return Json(ReturnModel.Fail("验证码错误"));
                }

                if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
                {
                    return Json(ReturnModel.Fail("用户名或密码不能为空"));
                }
                var user = await userService.Login(userName, password).ConfigureAwait(false);
                if (user == null)
                {
                    return Json(ReturnModel.Fail("用户名或密码错误"));
                }
                if (user.UserStatus != UserStatus.Init && user.UserStatus != UserStatus.Enable)
                {
                    return Json(ReturnModel.Fail("用户名状态：" + user.UserStatus.GetDescription()));
                }
                #region 认证、存入cookie
                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                List<Claim> claims = new();
                var currentUser = SerializeHelper.Serialize(user);
                claims.Add(new Claim(ClaimTypes.Name, user.RealName, ClaimValueTypes.String));
                claims.Add(new Claim(ClaimTypes.PrimarySid, user.Id.ToString(), ClaimValueTypes.String));
                claims.Add(new Claim(ClaimTypes.UserData, currentUser, ClaimValueTypes.String));
                identity.AddClaims(claims);
                var claimsPrincipal = new ClaimsPrincipal(identity);
                await HttpContext.SignInAsync(identity.AuthenticationType, claimsPrincipal,
                  new AuthenticationProperties
                  {
                      // 获取或设置身份验证会话是否跨多个服务器持久化请求:
                      // 此选项一般根据登录页是否勾选记住我来确定，
                      // true:在cookie没过期之前，关闭浏览器再打开用户是登录状态。
                      // false:不管cookie有没有过期只要关闭了浏览器再打开就要重新登录。
                      IsPersistent = remember,
                      // 获取或设置要用作http重定向响应值的完整路径或绝对URI
                      RedirectUri = "/Home/Index",
                  });
                #endregion
                HttpContext.Session.Remove(GlobalConst.CaptchaSessionName);
                return Json(ReturnModel.Success("登录成功", "/Home/Index"));
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "登录异常");
                return Json(ReturnModel.Fail("登录失败，请稍后重试"));
            }

        }

        public async Task<IActionResult> LoginOut()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return Redirect(GlobalConst.LoginPath);
        }
    }
}
